package be.ac.ua.pats.thesisrobotica.device.communication;

//~--- non-JDK imports --------------------------------------------------------

import be.ac.ua.pats.thesisrobotica.device.NXTRobot;
import be.ac.ua.pats.thesisrobotica.device.parser.MessageParser;

import lejos.pc.comm.*;

//~--- JDK imports ------------------------------------------------------------

import java.io.*;

/**
 * @author Jimmy
 */
public class Connection extends NXTConnector implements Runnable {
    Boolean          connected = false;
    DataInputStream  dis;
    DataOutputStream dos;
    NXTRobot         entity;
    MessageParser    parser;
    Thread           parserThread;

    public Connection() {
        this(null);

    }

    public Connection(NXTRobot robot) {
        super();

        this.entity = robot;
        parser      = new MessageParser(robot);

        System.out.println("Waiting for connection...");

        while (!connected) {
            connected = this.connectTo("btspp://");
        }

        System.out.println("Connected!");

        dos = this.getDataOut();
        dis = this.getDataIn();

                parserThread = new Thread(parser);
    }

    /**
     * Sends an integer over the connection.
     * Main purpose: for sending the String's length.
     *
     */
    private void send(int i) throws IOException {
        dos.writeInt(i);
        dos.flush();
    }

    /**
     * Sends a string over the connection.
     *
     * @param s The string to be sent.
     */
    public void send(String s) throws IOException {
        System.out.println("Going to send: " + s);

        char[] charArray = s.toCharArray();

        this.send(charArray.length);

        int i = 0;

        for (char c : charArray) {
            dos.writeChar(c);

            // flush after every 30. char
            if (i % 30 == 0) {
                dos.flush();
            }

            i++;
        }

        // Flush all
        dos.flush();
    }

    /**
     * Terminates the current connection.
     */
    public void disconnect() throws IOException {
        connected = false;

        dos.close();
        dis.close();
        this.close();
        System.out.println("Disconnected");
    }

    /**
     * Instantiates a messageParser-thread and (while connected) listens to
     * incoming messages, which will be parsed when received.
     */
    public void run() {
        try {
            System.out.println("Starting new parserThread");
            parserThread.start();
            System.out.println("Starting to listen");

            StringBuilder resString = new StringBuilder();

            while (connected) {
                int  stringLength = dis.readInt();
                char n;

                for (int i = 0; i < stringLength; i++) {
                    n = dis.readChar();

                    resString.append(n);
                }

                System.out.println("Received on PC side: " + resString.toString());
                parser.addMessage(resString.toString());

                resString = new StringBuilder();
            }
        } catch (IOException ex) {
            System.out.println("IOException in connection:run()");
        }
    }
}
